using System.Linq.Expressions;
using Ellwood.Manage.Common.Core.result;
using SqlSugar;

namespace Ellwood.Manage.Common.Core.Basis.Service;

/// <summary>
/// service基础类接口
/// </summary>
public interface IBaseService
{

    #region 基础方法--查询Query

    /// <summary>
    /// 主键查询
    /// </summary>
    /// <param name="id"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    T Find<T>(int id) where T : class;
    
    /// <summary>
    /// 主键查询--异步版本
    /// </summary>
    /// <param name="id"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    Task<T> FindAsync<T>(int id) where T : class;
    
    /// <summary>
    /// 提供对表单的查询
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns>ISugarQueryable类型集合</returns>
    [Obsolete("尽量避免使用，using带表达式的目录树的 代替")]
    ISugarQueryable<T> Set<T>() where T : class;

    /// <summary>
    /// 条件查询
    /// </summary>
    /// <param name="funcWhere"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    ISugarQueryable<T> Query<T>(Expression<Func<T,bool>> funcWhere) where T : class;

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="funcWhere"></param>
    /// <param name="pageSize"></param>
    /// <param name="pageIndex"></param>
    /// <param name="funcOrderBy"></param>
    /// <param name="isAsc"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    PagingData<T> QueryPage<T>(Expression<Func<T, bool>> funcWhere, int pageSize, int pageIndex,
        Expression<Func<T, object>> funcOrderBy, bool isAsc = true) where T : class;

    #endregion

    #region 基础方法--新增Add
    
    /// <summary>
    /// 新增数据-同步版本
    /// </summary>
    /// <param name="t"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    T Insert<T>(T t) where T : class,new();
    
    /// <summary>
    /// 新增数据-异步版本
    /// </summary>
    /// <param name="t"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    Task<T> InsertAsync<T>(T t) where T : class,new();
    
    /// <summary>
    /// 批量新增
    /// </summary>
    /// <param name="tList"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    Task<bool> InsertList<T>(List<T> tList) where T : class,new();
    #endregion

    #region 基础方法--更新Update

    /// <summary>
    /// 更新数据，即时Commit
    /// </summary>
    /// <param name="t"></param>
    /// <typeparam name="T"></typeparam>
    void Update<T>(T t) where T : class,new();
    
    /// <summary>
    /// 更新数据--异步版本，即时Commit
    /// </summary>
    /// <param name="t"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    Task UpdateAsync<T>(T t) where T : class,new();

    /// <summary>
    /// 更新数据，即时Commit
    /// </summary>
    /// <param name="tList"></param>
    /// <typeparam name="T"></typeparam>
    void Update<T>(List<T> tList) where T : class, new();

    #endregion

    #region 基础方法--删除Delete

    /// <summary>
    /// 根据主键删除数据
    /// </summary>
    /// <param name="pId"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    bool Delete<T>(object pId) where T : class, new();

    /// <summary>
    /// 根据主键删除数据--异步版本
    /// </summary>
    /// <param name="pId"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    Task<bool> DeleteAsync<T>(object pId) where T : class, new();
    
    /// <summary>
    /// 删除数据，即时Commit
    /// </summary>
    /// <param name="t"></param>
    /// <typeparam name="T"></typeparam>
    void Delete<T>(T t) where T : class, new();
    
    /// <summary>
    /// 根据集合删除数据，即时Commit
    /// </summary>
    /// <param name="tListt"></param>
    /// <typeparam name="T"></typeparam>
    void Delete<T>(List<T> tListt) where T : class, new();

    #endregion

    #region 基础方法--Other

    /// <summary>
    /// 执行sql,返回集合
    /// </summary>
    /// <param name="sql"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    ISugarQueryable<T> ExcuteQuery<T>(string sql) where T : class, new();

    #endregion
}